package utils

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	b64 "encoding/base64"
	"encoding/pem"
	"errors"
)

var privateKeyData = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCrGh1sc5AKD1EQ8WdA1iWF4m7wXtO6WoS7Dtfd0Jm2ud+LKBQ+
e7R6YIXnwfEKB/4Jm+jNtCi7/Zrx5gtEpUuVAyrEo5+qr5al5KibeJq3xyI/626I
BsDMFX5o3WOoXceTF7+lgi6r+OuokqFJgpeh7YANXQ8Y8mn8ucw+Ly+LbQIDAQAB
AoGAGgoxbC3yP/WwyrlSk4WD1Gpvo9lqs7PO+4D4zWNP4YVMRitlWVUOVImYF3tm
qbYprWCy/4tpn6KrECGImXvmkplXPxd4x3W+haZftx3VjTwh5fvT9yHp4swXxN+h
LMItDdIOWS4U6wVJa77Dy7VfK303LZrPLqnxkf4oEywp5YECQQDZOz1WD7nOqOiy
AlwDhfeLTmArN0f+gV6RLrxMp2XRqC2DN5nMq5O5BVVMK9LBgArNqYfxWYuMa3K2
qliRDPPxAkEAyaNWq/fDvjpK9TgztqsHIiG+cUQpWI759zt5qHNA+QF4L43dtAVZ
zBR/uam1jnRuM6K0ZCSZo2ITiqapmk8bPQJAEd9d3IbOssIS4xJun5uWElAQeX3C
3p2mOiuuMmBTcDx2AiXA8aXsMXzO18WDQYhXWzRniuPjJ1pvxbeeMdDvAQJBAMDh
uZAJEzrOAlQurfFICyvQQZ+Rx0dKhbzFLOxBS96mVDSRLYn+MFbzKPcOa3lY0O4d
7xd4l2td7zmLkePlVjUCQQCY8VuIfKc0+AWvPnktKXbx9bBdJZSDginZM5cu7pdx
W0uB9KZoLqgbGLIvWrLyA6SBqo87Q1j1//wFgLP+A2Gn
-----END RSA PRIVATE KEY-----
`)

//openssl
//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
var publicKeyData = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrGh1sc5AKD1EQ8WdA1iWF4m7w
XtO6WoS7Dtfd0Jm2ud+LKBQ+e7R6YIXnwfEKB/4Jm+jNtCi7/Zrx5gtEpUuVAyrE
o5+qr5al5KibeJq3xyI/626IBsDMFX5o3WOoXceTF7+lgi6r+OuokqFJgpeh7YAN
XQ8Y8mn8ucw+Ly+LbQIDAQAB
-----END PUBLIC KEY-----
`)

//私钥签名
func Sign(data []byte) (sign string, err error) {
	h := sha256.New()
	h.Write(data)
	hashed := h.Sum(nil)
	//priv, err := getPriKey(privateKey)
	//if err != nil {
	//	return "", err
	//}
	signData, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed)
	if err != nil {
		return "", err
	}
	sign = b64.StdEncoding.EncodeToString(signData)
	return sign, nil
}

//公钥验证
func SignVer(data []byte, signature string) error {
	signData, err := b64.StdEncoding.DecodeString(signature)
	if err != nil {
		return err
	}
	hashed := sha256.Sum256(data)
	//获取公钥
	//pub, err := getPubKey(publicKey)
	//if err != nil {
	//	return err
	//}

	//验证签名
	return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signData)
}

// 公钥加密
func Encrypt(data []byte) ([]byte, error) {
	//获取公钥
	//pub, err := getPubKey(publicKey)
	pub := publicKey
	//if err != nil {
	//	return nil, err
	//}
	//加密
	return rsa.EncryptPKCS1v15(rand.Reader, pub, data)
}

// 私钥解密,privateKey为pem文件里的字符
func Decrypt(encData []byte) ([]byte, error) {
	//解析PKCS1a或者PKCS8格式的私钥
	//priv, err := getPriKey(privateKey)
	//if err != nil {
	//	return nil, err
	//}
	// 解密
	return rsa.DecryptPKCS1v15(rand.Reader, privateKey, encData)
}

func getPubKey(publicKeyData []byte) (*rsa.PublicKey, error) {
	//解密pem格式的公钥
	block, _ := pem.Decode(publicKeyData)
	if block == nil {
		return nil, errors.New("public key error")
	}
	// 解析公钥
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	// 类型断言
	if pub, ok := pubInterface.(*rsa.PublicKey); ok {
		return pub, nil
	} else {
		return nil, errors.New("public key error")
	}
}

func getPriKey(privateKeyData []byte) (*rsa.PrivateKey, error) {
	//获取私钥
	block, _ := pem.Decode(privateKeyData)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	var priKey *rsa.PrivateKey
	var err error

	priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return priKey, nil
}

var privateKey, _ = getPriKey(privateKeyData)
var publicKey, _ = getPubKey(publicKeyData)
